共计 1724 个字符,预计需要花费 5 分钟才能阅读完成。
数据分析的基本流程,一般分为四个步骤(对应四个工作过程):
- 了解并确定问题,即数据收集
- 分解问题和数据,即数据清洗
- 评估与分析数据,即数据分析
- 得出结论和支持决策,即数据报告
读取数据
导库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
sns.set(style="darkgrid", font_scale=1.2)
plt.rcParams["font.family"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False
warnings.filterwarnings("ignore")
加载数据集
data = pd.read_csv("data.csv")
print(data.shape)
data.head()
data.sample()
数据清洗
符合整洁数据的三个特点:
- 每列是一个变量
- 每行是一个观察值
- 每个单元格是一个值
缺失值
缺失值探索
data.info()
t = data.isnull().sum()
t = pd.concat([t, t / len(data)], axis=1) # 左右拼接,横向拼接
t.columns = ["缺失值数量", "缺失值比例"]
display(t)
缺失值处理
对于缺失值,可以使用如下的方式处理 :
- 删除缺失值
- 仅适合于缺失数量很少的情况
- 填充缺失值
- 数值变量
- 均值填充
- 中值填充
- 插值填充
- 类别变量
- 众数填充
- 单独作为一个类别
- 额外处理说明
- 缺失值小于 20%,直接填充
- 缺失值在 20% ~ 80%,填充变量后,同时增加一列,标记该列是否缺失,参与后续建模
- 缺失值大于 80%,将该列转换为二值变量 (例如 1 与 0),用来表示记录是否缺失
- 数值变量
## 数据发布
print(data["CRIM"].skew())
sns.distplot(data["CRIM"].dropna())
## 右偏,可采用中位数填充
data.fillna({"CRIM": data["CRIM"].median()}, inplace=True)
异常值
异常值探索
data.describe() # 显示数据的统计信息,可作为一种简单的异常探索方式
根据正态分布的特性,可以将 3σ 之外的数据,视为异常值。
mean, std = data["CRIM"].mean(), data["CRIM"].std()
lower, upper = mean - 3 * std, mean + 3 * std
print("均值:", mean)
print("标准差:", std)
print("下限:", lower)
print("上限:", upper)
## 获取在 3 倍标准差之外的数据
data["CRIM"][(data["CRIM"] < lower) | (data["CRIM"] > upper)]
箱线图是一种常见的异常检测方式,其采用四分位的方式进行检测。
sns.boxplot(data=data["CRIM"])
异常值处理
对于异常值,可以采用如下的方式处理 :
- 删除异常值
- 视为缺失值处理
- 对数转换
- 使用临界值填充(在 3σ 与箱线图中,可以这样来处理)
- 使用分箱法离散化处理
如果数据中存在较大的异常值,可以通过取对数来进行转换,这样可以得到一定的缓解。例如,变量呈现右偏分布(不适合左偏分布),可以进行取对数转换。
fig, ax = plt.subplots(1, 2) # 子图的行列数
fig.set_size_inches(15, 5)
sns.distplot(data["CRIM"], ax=ax[0])
sns.distplot(np.log(data["CRIM"]), ax=ax[1])
取对数的方式比较简单,不过也存在一些局限:取对数只能针对正数操作。不过可以通过如下的方式进行转换:
np.sign(x) * np.log(np.abs(x) + 1)
重复值
重复值探索
print(data.duplicated().sum()) # 发现重复值
data[data.duplicated(keep=False)] # 查看哪些记录出现了重复值
重复值处理
data.drop_duplicates(inplace=True) # 直接删除重复值
正文完